/*
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details:
 * http://www.gnu.org/copyleft/lesser.html#TOC3
 */
package com.simplemonkey.appearance;

import com.simplemonkey.IWidget;
import com.simplemonkey.util.Dimension;
import com.simplemonkey.util.Spacing;

/**
 * Holds appearance properties. 
 * 
 * * The following ASCII-Art is supposed to illustrate the
 * margins.
 * <pre>
 * +---------------------------------------------------------------------------------------------------+
 * |                                                |                                                  |
 * |                                          Outer Margin Top                                         |
 * |                                                |                                                  |
 * |            +-------------------------------------------------------------------------+            |
 * |            |                                   |                                     |            |
 * |            |                              Border Top                                 |            |
 * |            |                                   |                                     |            |
 * |            |            +-----------------------------------------------+            |            |
 * |            |            |                      |                        |            |            |
 * |            |            |                 Padding Top                   |            |            |
 * |            |            |                      |                        |            |            |
 * |            |            |             +-------------------+             |            |            |
 * |   Outer    |            |             |        |          |             |            |   Outer    |
 * |<- Margin ->|<- Border ->|<- Padding ->|<-  Inner Width  ->|<- Padding ->|<- Border ->|<- Margin ->|
 * |    Left    |    Left    |     Left    |        |          |    Right    |    Right   |   Right    |
 * |            |            |             +-------------------+             |            |            |
 * |            |            |                      |                        |            |            |
 * |            |            |                Padding Bottom                 |            |            |
 * |            |            |                      |                        |            |            |
 * |            |            +-----------------------------------------------+            |            |
 * |            |                                   |                                     |            |
 * |            |                             Border Bottom                               |            |
 * |            |                                   |                                     |            |
 * |            +-------------------------------------------------------------------------+            |
 * |                                                |                                                  |
 * |                                     Outer Margin Bottom                                           |
 * |                                                |                                                  |
 * +---------------------------------------------------------------------------------------------------+
 * </pre>
 * @author Johannes Schaback, last edited by $Author: marcmenghin $, $Date: 2008-06-24 03:08:17 -0700 (Tue, 24 Jun 2008) $
 * @version $Revision: 569 $
 * @dedication Lagwagon - Stokin' the Neighbors
 */
public class SpacingAppearance
{
	private Spacing margin = Spacing.ZERO_SPACING;
	private Spacing border = Spacing.ZERO_SPACING;
	private Spacing padding = Spacing.ZERO_SPACING;
	private IWidget widget = null;

	public SpacingAppearance(IWidget w)
	{
		this.widget = w;
	}

	/**
	 * Copy constructor
	 * 
	 * @param w
	 * @param appearance
	 */
	public SpacingAppearance(IWidget w, SpacingAppearance appearance)
	{
		this(w);
		widget = w;
		this.margin = new Spacing(appearance.margin);
		this.border = new Spacing(appearance.border);
		this.padding = new Spacing(appearance.padding);
	}

	/**
	 * Returns the space reserved for borders.
	 * @return the border spacing
	 */
	public Spacing getBorder()
	{
		return border;
	}

	public IWidget getWidget()
	{
		return widget;
	}

	/**
	 * Reserves space for the border. Do not confuse with addBorder().
	 * @param border the spacing which says how much space to reserve
	 */
	public void setBorder(Spacing border)
	{
		if (border == null)
			border = Spacing.ZERO_SPACING;

		this.border = border;
		getWidget().updateMinSize();
	}

	public Spacing getMargin()
	{
		return margin;
	}

	public void setMargin(Spacing margin)
	{
		if (margin == null)
			margin = Spacing.ZERO_SPACING;

		this.margin = margin;
		getWidget().updateMinSize();
	}

	public Spacing getPadding()
	{
		return padding;
	}

	public void setPadding(Spacing padding)
	{
		if (padding == null)
			padding = Spacing.ZERO_SPACING;

		this.padding = padding;
		getWidget().updateMinSize();
	}

	public void clearSpacings()
	{
		clearSpacings(Spacing.ZERO_SPACING);
	}

	public void clearSpacings(Spacing clearSpacing)
	{
		this.margin = clearSpacing;
		this.border = clearSpacing;
		this.padding = clearSpacing;
	}

	public final Dimension getMinSizeHint()
	{
		Dimension contentSize = this.getWidget().getMinContentSize();

		if (contentSize == null)
			return new Dimension(10, 10);
		
		
		Dimension minSizeHint = new Dimension(0,0);
		minSizeHint.setSize(contentSize.getWidth() + border.getLeftPlusRight() + margin.getLeftPlusRight()	+ padding.getLeftPlusRight(),
				contentSize.getHeight() + border.getBottomPlusTop() + margin.getBottomPlusTop() + padding.getBottomPlusTop());
		
		return minSizeHint; 
	}


	/**
	 * Return how much height in pixels is available to draw the content.
	 * @return available space for content
	 */
	public float getContentWidth()
	{
		return widget.getSize().getWidth() - border.getLeftPlusRight() - margin.getLeftPlusRight()
				- padding.getLeftPlusRight();
	}

	/**
	 * Return how much width in pixels is available to draw the content.
	 * @return available space for content
	 */
	public float getContentHeight()
	{
		return widget.getSize().getHeight() - border.getBottomPlusTop() - margin.getBottomPlusTop()
				- padding.getBottomPlusTop();
	}

	/**
	 * Returns if the specified point lays inside the box
	 * without margin.
	
	 * @param pX The x-coordinate of the position to test.
	 * @param pY The y-coordinate of the position to test.
	 * @return Whether or not the point was inside the box.
	 */
	public final boolean insideMargin(float pX, float pY)
	{
		// translating pX, pY to the inner Box
		pX -= margin.getLeft();
		pY -= margin.getBottom();

		float innerWidth = getContentWidth();
		float innerHeight = getContentHeight();

		return pX >= 0
				&& pX < innerWidth + padding.getLeft() + padding.getRight() + getBorder().getLeft() + getBorder().getRight()
				&& pY >= 0
				&& pY < innerHeight + padding.getBottom() + padding.getTop() + getBorder().getTop() + getBorder().getBottom();
	}

	/**
	 * Returns the sum of bottom margin, bottom border and the
	 * bottom padding.
	 * @return sum
	 */
	public float getBottomMargins()
	{
		return margin.getBottom() + getBorder().getBottom() + padding.getBottom();
	}

	/**
	 * Returns the sum of the top margin, top border and top padding.
	 * @return sum
	 */
	public float getTopMargins()
	{
		return margin.getTop() + getBorder().getTop() + padding.getTop();
	}

	/**
	 * Returns the sum of the left margin, left border and left 
	 * padding.
	 * @return sum
	 */
	public float getLeftMargins()
	{
		return margin.getLeft() + getBorder().getLeft() + padding.getLeft();
	}

	/**
	 * Returns the sum of the right margin, right border and
	 * right padding.
	 * @return sum
	 */
	public float getRightMargins()
	{
		return margin.getRight() + getBorder().getRight() + padding.getRight();
	}

	public float getContentMinWidth()
	{
		return getWidget().getMinSize().getWidth() - getLeftMargins() - getRightMargins();
	}

	public float getContentMinHeight()
	{
		return getWidget().getMinSize().getWidth() - getTopMargins() - getBottomMargins();
	}

	public Dimension getContentSize()
	{
		return new Dimension(getContentWidth(),getContentHeight());
	}
	
	@Override
	public String toString()
	{
		String s = "";
		s += "content size         : " + getContentWidth() + ", " + getContentHeight() + "\n";
		s += "content min size hint: " + getWidget().getMinContentSize() + "\n";
		s += "padding              : " + getPadding() + "\n";
		s += "border               : " + getBorder() + "\n";
		s += "margin               : " + getMargin();
		return s;
	}


}
